package org.app.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.app.entity.Activity;
import org.app.entity.ActivityParticipant;
import org.app.entity.User;
import org.app.exception.BusinessException;
import org.app.mapper.ActivityMapper;
import org.app.mapper.ActivityParticipantMapper;
import org.app.mapper.UserMapper;
import org.app.service.ActivityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ActivityServiceImpl extends ServiceImpl<ActivityMapper, Activity> implements ActivityService {
    
    @Autowired
    private ActivityParticipantMapper activityParticipantMapper;
    
    @Autowired
    private UserMapper userMapper;
    
    @Override
    public Page<Activity> getActivityPage(Integer pageNum, Integer pageSize, Integer status) {
        return getActivityPage(pageNum, pageSize, status, null);
    }
    
    @Override
    public Page<Activity> getActivityPage(Integer pageNum, Integer pageSize, Integer status, String keyword) {
        // 只查询已发布的活动（用户端显示）
        LambdaQueryWrapper<Activity> queryWrapper = new LambdaQueryWrapper<>();
        
        // 如果有状态筛选
        if (status != null) {
            queryWrapper.eq(Activity::getStatus, status);
        } else {
            // 默认显示已发布
            queryWrapper.eq(Activity::getStatus, 1);
        }
        
        // 如果有关键词
        if (StringUtils.hasText(keyword)) {
            queryWrapper.and(w -> w
                .like(Activity::getTitle, keyword)
                .or()
                .like(Activity::getDescription, keyword)
                .or()
                .like(Activity::getLocation, keyword)
            );
        }
        
        // 按照创建时间降序排序
        queryWrapper.orderByDesc(Activity::getCreateTime);
        
        return page(new Page<>(pageNum, pageSize), queryWrapper);
    }
    
    @Override
    public Page<Activity> getAdminActivityPage(Integer pageNum, Integer pageSize, Integer status) {
        return getAdminActivityPage(pageNum, pageSize, status, null);
    }
    
    @Override
    public Page<Activity> getAdminActivityPage(Integer pageNum, Integer pageSize, Integer status, String keyword) {
        // 管理端查询所有活动
        LambdaQueryWrapper<Activity> queryWrapper = new LambdaQueryWrapper<>();
        
        // 如果有状态筛选
        if (status != null) {
            queryWrapper.eq(Activity::getStatus, status);
        }
        
        // 如果有关键词
        if (StringUtils.hasText(keyword)) {
            queryWrapper.and(w -> w
                .like(Activity::getTitle, keyword)
                .or()
                .like(Activity::getDescription, keyword)
                .or()
                .like(Activity::getLocation, keyword)
            );
        }
        
        // 按照创建时间降序排序
        queryWrapper.orderByDesc(Activity::getCreateTime);
        
        return page(new Page<>(pageNum, pageSize), queryWrapper);
    }
    
    @Override
    @Transactional
    public Boolean signup(Long activityId, Long userId) {
        // 判断活动是否存在且状态为已发布
        Activity activity = getById(activityId);
        log.info(activity.toString());
        if (activity == null) {
            throw new BusinessException("活动不存在");
        }
        
        // 判断活动状态是否为"报名中"(1)
        if (activity.getStatus() != 1) {
            if (activity.getStatus() == 0) {
                throw new BusinessException("活动尚未开始报名");
            } else if (activity.getStatus() == 2) {
                throw new BusinessException("活动已结束");
            } else {
                throw new BusinessException("活动状态异常，无法报名");
            }
        }
        
        // 判断是否已经报名
        if (isSignedUp(activityId, userId)) {
            throw new BusinessException("您已经预约过此活动");
        }
        
        // 判断报名人数是否已满
        if (activity.getCurrentParticipants() >= activity.getMaxParticipants()) {
            throw new BusinessException("活动名额已满");
        }
        
        // 创建报名记录
        ActivityParticipant participant = new ActivityParticipant();
        participant.setActivityId(activityId);
        participant.setUserId(userId);
        participant.setSignupTime(LocalDateTime.now());
        participant.setStatus(1); // 正常状态
        activityParticipantMapper.insert(participant);
        
        // 更新活动参与人数
        activity.setCurrentParticipants(activity.getCurrentParticipants() + 1);
        updateById(activity);
        return true;
    }
    
    @Override
    @Transactional
    public void cancelSignup(Long activityId, Long userId) {
        // 判断活动是否存在
        Activity activity = getById(activityId);
        if (activity == null) {
            throw new RuntimeException("活动不存在");
        }
        
        // 判断是否已经报名
        if (!isSignedUp(activityId, userId)) {
            throw new RuntimeException("您未报名过该活动");
        }
        
        // 删除报名记录
        LambdaQueryWrapper<ActivityParticipant> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ActivityParticipant::getActivityId, activityId)
                   .eq(ActivityParticipant::getUserId, userId);
        activityParticipantMapper.delete(queryWrapper);
        
        // 更新活动参与人数
        activity.setCurrentParticipants(activity.getCurrentParticipants() - 1);
        updateById(activity);
    }
    
    @Override
    public boolean isSignedUp(Long activityId, Long userId) {
        if (activityId == null || userId == null) {
            return false;
        }
        
        LambdaQueryWrapper<ActivityParticipant> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ActivityParticipant::getActivityId, activityId)
                   .eq(ActivityParticipant::getUserId, userId);
        return activityParticipantMapper.selectCount(queryWrapper) > 0;
    }
    
    @Override
    public int getParticipantCount(Long activityId) {
        LambdaQueryWrapper<ActivityParticipant> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ActivityParticipant::getActivityId, activityId);
        return activityParticipantMapper.selectCount(queryWrapper).intValue();
    }
    
    @Override
    @Transactional
    public void updateStatus(Long activityId, Integer status) {
        Activity activity = getById(activityId);
        if (activity == null) {
            throw new RuntimeException("活动不存在");
        }
        
        activity.setStatus(status);
        updateById(activity);
    }
    
    @Override
    public List<Map<String, Object>> getActivityParticipants(Long activityId) {
        // 查询报名用户
        LambdaQueryWrapper<ActivityParticipant> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ActivityParticipant::getActivityId, activityId)
                   .orderByDesc(ActivityParticipant::getSignupTime);
        List<ActivityParticipant> participants = activityParticipantMapper.selectList(queryWrapper);
        
        if (participants.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 获取用户ID列表
        List<Long> userIds = participants.stream()
                                        .map(ActivityParticipant::getUserId)
                                        .collect(Collectors.toList());
        
        // 查询用户信息
        LambdaQueryWrapper<User> userQueryWrapper = new LambdaQueryWrapper<>();
        userQueryWrapper.in(User::getId, userIds);
        List<User> users = userMapper.selectList(userQueryWrapper);
        
        // 转换为用户ID映射
        Map<Long, User> userMap = users.stream()
                                      .collect(Collectors.toMap(User::getId, user -> user));
        
        // 构建结果
        return participants.stream().map(p -> {
            Map<String, Object> map = new HashMap<>();
            User user = userMap.get(p.getUserId());
            
            map.put("id", p.getUserId());
            map.put("username", user != null ? user.getUsername() : "未知用户");
            map.put("phone", user != null ? user.getPhone() : "");
            map.put("registerTime", p.getSignupTime());
            
            return map;
        }).collect(Collectors.toList());
    }
    
    @Override
    public Map<String, Object> getActivityStats() {
        Map<String, Object> stats = new HashMap<>();
        
        // 总活动数
        stats.put("totalActivities", count());
        
        // 已发布活动数量
        LambdaQueryWrapper<Activity> publishedQuery = new LambdaQueryWrapper<>();
        publishedQuery.eq(Activity::getStatus, 1);
        stats.put("publishedActivities", count(publishedQuery));
        
        // 草稿活动数量
        LambdaQueryWrapper<Activity> draftQuery = new LambdaQueryWrapper<>();
        draftQuery.eq(Activity::getStatus, 0);
        stats.put("draftActivities", count(draftQuery));
        
        // 已结束活动数量
        LambdaQueryWrapper<Activity> finishedQuery = new LambdaQueryWrapper<>();
        finishedQuery.eq(Activity::getStatus, 2);
        stats.put("finishedActivities", count(finishedQuery));
        
        // 总报名人次
        int totalParticipants = 0;
        try {
            totalParticipants = activityParticipantMapper.selectCount(null).intValue();
        } catch (Exception e) {
            e.printStackTrace();
        }
        stats.put("totalParticipants", totalParticipants);
        
        // 最近一周的活动数量
        LambdaQueryWrapper<Activity> recentQuery = new LambdaQueryWrapper<>();
        recentQuery.ge(Activity::getCreateTime, LocalDateTime.now().minusDays(7));
        stats.put("recentActivities", count(recentQuery));
        
        return stats;
    }
    
    @Override
    public List<Activity> getTopActivitiesForBanner(int limit) {
        LambdaQueryWrapper<Activity> queryWrapper = new LambdaQueryWrapper<>();
        // 只查询已发布的活动且有封面图的活动
        queryWrapper.eq(Activity::getStatus, 1)
                    .isNotNull(Activity::getCover)
                    .ne(Activity::getCover, "");
        
        // 按照创建时间倒序排序
        queryWrapper.orderByDesc(Activity::getCreateTime);
        
        // 限制返回数量
        Page<Activity> page = new Page<>(1, limit);
        page(page, queryWrapper);
        
        return page.getRecords();
    }
    
    @Override
    public List<Activity> getRecentActivities(int limit) {
        LambdaQueryWrapper<Activity> queryWrapper = new LambdaQueryWrapper<>();
        // 只查询已发布的活动
        queryWrapper.eq(Activity::getStatus, 1);
        
        // 按照创建时间倒序排序
        queryWrapper.orderByDesc(Activity::getCreateTime);
        
        // 限制返回数量
        Page<Activity> page = new Page<>(1, limit);
        page(page, queryWrapper);
        
        return page.getRecords();
    }
    
    /**
     * 自动更新活动状态
     * 定时任务调用此方法，自动更新活动状态
     */
    @Override
    @Transactional
    public void autoUpdateActivityStatus() {
        LocalDateTime now = LocalDateTime.now();
        
        // 查询所有活动
        List<Activity> activities = list();
        
        for (Activity activity : activities) {
            // 未开始的活动，如果当前时间到了开始时间，则更新为报名中
            if (activity.getStatus() == 0 && now.isAfter(activity.getStartTime())) {
                activity.setStatus(1);
                updateById(activity);
                log.info("活动[{}]状态自动更新为报名中", activity.getId());
            }
            
            // 报名中的活动，如果当前时间超过了结束时间，则更新为已结束
            if (activity.getStatus() == 1 && now.isAfter(activity.getEndTime())) {
                activity.setStatus(2);
                updateById(activity);
                log.info("活动[{}]状态自动更新为已结束", activity.getId());
            }
        }
    }
    
    @Override
    public Page<Activity> getMyActivities(Integer pageNum, Integer pageSize, Long userId) {
        // 查询用户参与的活动ID列表
        LambdaQueryWrapper<ActivityParticipant> participantQuery = new LambdaQueryWrapper<>();
        participantQuery.eq(ActivityParticipant::getUserId, userId);
        List<ActivityParticipant> participants = activityParticipantMapper.selectList(participantQuery);
        
        if (participants.isEmpty()) {
            return new Page<>(pageNum, pageSize);
        }
        
        // 获取活动ID列表
        List<Long> activityIds = participants.stream()
                .map(ActivityParticipant::getActivityId)
                .collect(Collectors.toList());
        
        // 查询活动列表
        LambdaQueryWrapper<Activity> activityQuery = new LambdaQueryWrapper<>();
        activityQuery.in(Activity::getId, activityIds)
                    .orderByDesc(Activity::getCreateTime);
        
        return page(new Page<>(pageNum, pageSize), activityQuery);
    }
} 